﻿using System;
using System.IO;

namespace JY.Common.Helpers
{
    /// <summary>
    /// 文件监控系统帮助类
    /// </summary>
    public class FileSystemWatcherHelper
    {
        private FileSystemWatcher _fileSystemWatcher;
        /// <summary>
        /// 文件变更回调
        /// </summary>
        /// <remarks>
        /// WatcherChangeTypes  变更类型
        /// string  文件路径
        /// string  文件名称
        /// </remarks>
        public Action<WatcherChangeTypes, string, string> FileChangedAction { get; set; }
        /// <summary>
        /// 文件名称变更回调
        /// </summary>
        /// <remarks>
        /// WatcherChangeTypes  变更类型
        /// string  旧文件路径
        /// string  旧文件名称
        /// string  文件路径
        /// string  文件名称
        /// </remarks>
        public Action<WatcherChangeTypes, string, string, string, string> FileRenamedAction { get; set; }

        #region # 构造器
        /// <summary>
        /// 构造器
        /// </summary>
        public FileSystemWatcherHelper()
        {
        }
        /// <summary>
        /// 构造器
        /// </summary>
        /// <param name="watcherPath">监控文件路径</param>
        /// <param name="filter">文件类型</param>
        public FileSystemWatcherHelper(string watcherPath, string filter="")
        {

            try
            {
                this._fileSystemWatcher = new FileSystemWatcher();
                this._fileSystemWatcher.Path = watcherPath;
                if (!string.IsNullOrEmpty(filter))
                {
                    this._fileSystemWatcher.Filter = filter;
                }

                this._fileSystemWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.DirectoryName;
                this._fileSystemWatcher.IncludeSubdirectories = true;
                this._fileSystemWatcher.Created += new FileSystemEventHandler(FileWatcher_Created);
                this._fileSystemWatcher.Changed += new FileSystemEventHandler(FileWatcher_Changed);
                this._fileSystemWatcher.Deleted += new FileSystemEventHandler(FileWatcher_Deleted);
                this._fileSystemWatcher.Renamed += new RenamedEventHandler(FileWatcher_Renamed);
            }
            catch (Exception ex)
            {
                Console.WriteLine($@"初始化异常:{ex.Message}");
            }
        } 
        #endregion

        #region # 启动监视——void Start()
        /// <summary>
        /// 启动监视
        /// </summary>
        public void Start()
        {
            this._fileSystemWatcher.EnableRaisingEvents = true;
            Console.WriteLine("文件监控已经启动...");
        }
        #endregion

        #region # 停止监视——void Stop()
        /// <summary>
        /// 停止监视
        /// </summary>
        public void Stop()
        {
            this._fileSystemWatcher.EnableRaisingEvents = false;
            this._fileSystemWatcher.Dispose();
            this._fileSystemWatcher = null;
        }
        #endregion

        #region # 事件
        /// <summary>
        /// 文件创建
        /// </summary>
        protected void FileWatcher_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("新增:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);
            this.FileChangedAction?.Invoke(e.ChangeType,e.FullPath,e.Name);
        }
        /// <summary>
        /// 文件变更
        /// </summary>
        protected void FileWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("变更:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);
            this.FileChangedAction?.Invoke(e.ChangeType, e.FullPath, e.Name);
        }
        /// <summary>
        /// 文件删除
        /// </summary>
        protected void FileWatcher_Deleted(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("删除:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);
            this.FileChangedAction?.Invoke(e.ChangeType, e.FullPath, e.Name);
        }
        /// <summary>
        /// 文件重命名
        /// </summary>
        protected void FileWatcher_Renamed(object sender, RenamedEventArgs e)
        {
            Console.WriteLine("重命名: OldPath:{0} NewPath:{1} OldFileName{2} NewFileName:{3}", e.OldFullPath, e.FullPath, e.OldName, e.Name);
            this.FileRenamedAction?.Invoke(e.ChangeType, e.OldFullPath, e.OldName, e.FullPath, e.Name);
        }
        #endregion

    }
}
